﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Design;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WenSkin.Controls
{
    public class WenProgressListBox : ListBox
    {
        private WenProgressListBoxCollection items;

        public WenProgressListBox()
        {
            base.SetStyle(
                //ControlStyles.UserPaint |
                ControlStyles.DoubleBuffer |
                ControlStyles.OptimizedDoubleBuffer |
                ControlStyles.AllPaintingInWmPaint |
                ControlStyles.ResizeRedraw |
                ControlStyles.SupportsTransparentBackColor, true);
            base.UpdateStyles();
            this.DrawMode = DrawMode.OwnerDrawFixed;
            this.IntegralHeight = false;
            this.BorderStyle = BorderStyle.FixedSingle;
            ItemHeight = 23;
            this.SelectedIndexChanged += WenProgressListBox_SelectedIndexChanged;
        }

        private void WenProgressListBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.Invalidate();
        }

        [DefaultValue(DrawMode.OwnerDrawFixed)]
        public override DrawMode DrawMode { get => base.DrawMode; set => base.DrawMode = value; }


        #region  公有属性 

        [Category("颜色"), Description("选中颜色"), DefaultValue(typeof(Color),"61,61,61")]
        public Color SelectedColor { get; set; } = Color.FromArgb(61, 61, 61);

        #endregion

        protected override void OnDrawItem(DrawItemEventArgs e)
        {
            base.OnDrawItem(e);
            if (Items.Count == 0 || e.Index < 0)
                return;

            var item = this.Items[e.Index];

            Graphics g = e.Graphics.SetGDIHigh();
            Rectangle rec = GetItemRectangle(e.Index);
            //rec.Offset(-1, -1);
            if (this.GetSelected(e.Index))
            {
                rec.Inflate(0, -1);
            }
            //rec.Inflate(-1, -1);


            using var fc = new SolidBrush(ForeColor);
            using var bc = new SolidBrush(BackColor);
            using var sc = new SolidBrush(this.SelectedColor);

            using var tc = new SolidBrush(this.GetSelected(e.Index) ? Color.White : this.ForeColor);



            //获取进度条比例
            float v = (float)item.Value / item.MaxValue * rec.Width;

            if (this.GetSelected(e.Index))
                g.FillRectangle(sc, rec);
            else
                g.FillRectangle(bc, rec);

            g.FillRectangle(Brushes.Green, rec.X, rec.Y, v, rec.Height);

            g.DrawString(item?.ToString(), this.Font, tc, rec.X, rec.Y);
        }

        //[Editor("System.Windows.Forms.Design.ListControlStringCollectionEditor", typeof(UITypeEditor))]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public new WenProgressListBoxCollection Items
        {
            get
            {
                return this.items ??= new WenProgressListBoxCollection(this);
            }
        }
        private ObjectCollection BaseItems => base.Items;

        public class WenProgressListBoxCollection : IList
        {
            private readonly WenProgressListBox owner;
            private readonly ObjectCollection ls;
            public WenProgressListBox WenProgressListBox => owner;

            public int Count => ls.Count;

            public bool IsSynchronized => true;

            public object SyncRoot => true;

            public bool IsFixedSize => false;

            public bool IsReadOnly => ls.IsReadOnly;

            object IList.this[int index] { get => ls[index] as WenProgressListBoxItem; set => ls[index] = value; }
            public WenProgressListBoxItem this[int index] { get => ls[index] as WenProgressListBoxItem; set => ls[index] = value; }

            public WenProgressListBoxCollection(WenProgressListBox owner)
            {
                this.owner = owner;
                this.ls = owner.BaseItems;
            }

            public int Add(object value)
            {
                if (!(value is WenProgressListBoxItem item))
                    item = new WenProgressListBoxItem(value.ToString()) { Tag = value };
                item.Items = this;
                return ls.Add(item);
            }

            public void AddRange(WenProgressListBoxItem[] vas)
            {
                vas.ToList().ForEach(x => x.Items = this);
                ls.AddRange(vas);
            }

            public void Insert(int index, object value)
            {
                if (!(value is WenProgressListBoxItem item))
                    item = new WenProgressListBoxItem(value.ToString());
                item.Items = this;
                ls.Insert(index, item);
            }

            public int Add(WenProgressListBoxItem value)
            {
                value.Items = this;
                return ls.Add(value);
            }

            public void Clear()
            {
                ls.Clear();
            }

            public void CopyTo(WenProgressListBoxItem[] array, int index)
            {
                ls.CopyTo(array, index);
            }

            public IEnumerator GetEnumerator()
            {
                return ls.GetEnumerator();
            }

            public void CopyTo(Array array, int index)
            {
                List<object> list = new List<object>();
                foreach (var item in array)
                {
                    list.Add(item);
                }

                ls.CopyTo(list.ToArray(), index);
            }

            public bool Contains(object value)
            {
                return ls.Contains(value);
            }

            public int IndexOf(object value)
            {
                return ls.IndexOf(value);
            }

            public void Remove(object value)
            {
                ls.Remove(value);
            }

            public void RemoveAt(int index)
            {
                ls.RemoveAt(index);
            }
        }


        public class WenProgressListBoxItem
        {
            private int value = 0;
            private string text = "";

            public WenProgressListBoxItem()
            {
            }

            public WenProgressListBoxItem(string text)
            {
                this.Name = text;
                Text = text;
            }

            public WenProgressListBoxItem(string text, string name)
            {
                Name = name;
                Text = text;
            }

            public WenProgressListBoxCollection Items { get; set; }
            public WenProgressListBox ListBox => Items?.WenProgressListBox;
            private int Index => Items?.IndexOf(this) ?? -1;

            public string Name { get; set; } = "";
            public string Text
            {
                get => text;
                set
                {
                    text = value;
                    if (this.ListBox is null || this.Index < 0)
                        return;
                    var rec = this.ListBox.GetItemRectangle(this.Index);
                    this.ListBox.Invalidate(rec);
                }
            }
            public int Value
            {
                get => value;
                set
                {
                    this.value = value;
                    if (this.ListBox is null || this.Index < 0)
                        return;
                    var rec = this.ListBox.GetItemRectangle(this.Index);
                    this.ListBox.Invalidate(rec);
                }
            }
            public int MaxValue { get; set; } = 100;
            public int MinValue { get; set; } = 0;
            public object Tag { get; set; }
            public override string ToString()
            {
                return string.IsNullOrWhiteSpace(Text) ? this.Name : Text;
            }
        }
    }
}